package com.example.javasdktest01.controller;

import com.example.javasdktest01.entity.Trace;
import com.example.javasdktest01.fabric.FabricClient;
import com.example.javasdktest01.fabric.UserContext;
import com.example.javasdktest01.fabric.UserUtils;
import com.example.javasdktest01.repository.TraceRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.*;
//----------------------------------------------
import org.bouncycastle.crypto.CryptoException;
import org.hyperledger.fabric.sdk.*;

import org.hyperledger.fabric.sdk.exception.InvalidArgumentException;
import org.hyperledger.fabric.sdk.exception.ProposalException;
import org.hyperledger.fabric.sdk.exception.TransactionException;
import org.json.JSONException;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import javax.json.*;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Type;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.*;


@RestController
@RequestMapping("/fabric")
public class TraceHandler {

    private static final String keyFolderPath = "E:\\projectgo\\模拟\\src\\main\\resources\\crypto-config\\peerOrganizations\\org1.example.com\\users\\Admin@org1.example.com\\msp\\keystore";
    private static final String keyFileName = "dedac4ec716f71d3b2516a0ac0defb745e197932f55a03eebe025300e8c22a40_sk";
    private static final String certFoldePath = "E:\\projectgo\\模拟\\src\\main\\resources\\crypto-config\\peerOrganizations\\org1.example.com\\users\\Admin@org1.example.com\\msp\\signcerts";
    private static final String certFileName = "Admin@org1.example.com-cert.pem";
    private static final String txfilePath = "E:\\projectgo\\模拟\\src\\main\\resources\\test.tx";
    //order节点的tls证书
    private static final String ordertlsFilePath = "E:\\projectgo\\模拟\\src\\main\\resources\\crypto-config\\ordererOrganizations\\example.com\\tlsca\\tlsca.example.com-cert.pem";
    //peer1.org1的tls证书
    private static final String peer1tlsFilePath = "E:\\projectgo\\模拟\\src\\main\\resources\\crypto-config\\peerOrganizations\\org1.example.com\\peers\\peer1.org1.example.com\\msp\\tlscacerts\\tlsca.org1.example.com-cert.pem";
    //peer0.org1的tls证书
    private static final String peer0tlsFilePath = "E:\\projectgo\\模拟\\src\\main\\resources\\crypto-config\\peerOrganizations\\org1.example.com\\peers\\peer0.org1.example.com\\msp\\tlscacerts\\tlsca.org1.example.com-cert.pem";
    //peer0.org2的tls证书
    private static final String peerorg2tlsFilePath = "E:\\projectgo\\模拟\\src\\main\\resources\\crypto-config\\peerOrganizations\\org2.example.com\\tlsca\\tlsca.org2.example.com-cert.pem";



    @Autowired
    private TraceRepository traceRepository;


    @GetMapping("/findAll/{page}/{size}")
    public Page<Trace> findAll(@PathVariable("page") Integer page, @PathVariable("size") Integer size){
        Pageable pageable = PageRequest.of(page-1,size);
        return traceRepository.findAll(pageable);
    }


    @GetMapping("/findById/{id}")
    public JSONObject finedById(@PathVariable("id") Integer id) throws InvalidKeySpecException, NoSuchAlgorithmException, CryptoException, IOException, IllegalAccessException, InvalidArgumentException, InstantiationException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, org.hyperledger.fabric.sdk.exception.CryptoException, ProposalException, TransactionException {
        UserContext userContext = new UserContext();
        //userContext有某个组织的成员变量
        userContext.setAffiliation("Org1");//设置组织机构
        userContext.setMspId("Org1MSP");   //组织一的MSPID
        userContext.setAccount("dalin");
        userContext.setName("admin");
        Enrollment enrollment = UserUtils.getEnrollment(keyFolderPath,keyFileName,certFoldePath,certFileName);
        userContext.setEnrollment(enrollment);
        FabricClient fabricClient = new FabricClient(userContext);
        Peer peer0 = fabricClient.getPeer("peer0.org1.example.com","grpcs://peer0.org1.example.com:7051",peer0tlsFilePath);
        Peer peer1 = fabricClient.getPeer("peer1.org1.example.com","grpcs://peer1.org1.example.com:8051",peer1tlsFilePath);
        List<Peer> peers = new ArrayList<Peer>();

        String str = Integer.toString(id);
        String initArgs[] = {str};

        peers.add(peer0);
        peers.add(peer1);
        Map map = fabricClient.queryChaincode(peers,"mychannel",TransactionRequest.Type.GO_LANG,"eight","queryHistory",initArgs);
        String first = StringUtils.strip(map.values().toString(),"[{}]");
        first ="{"+"\"data\":[{"+first+"}}]}";
        System.out.println(first);
        System.out.println("===============");
        JSONObject jsonObject = JSONObject.fromObject(first);
        System.out.println(jsonObject.getString("data"));

        return jsonObject;
    }

    @GetMapping("/findproById/{id}")
    public Trace findById(@PathVariable("id") Integer id){
        return traceRepository.findById(id).get();
    }


    @DeleteMapping("/deleteById/{id}")
    public void deleteById(@PathVariable("id") Integer id){
        traceRepository.deleteById(id);
    }


    @PutMapping("/updata")
    public String updata(@RequestBody Trace trace) throws InvalidKeySpecException, NoSuchAlgorithmException, CryptoException, IOException, IllegalAccessException, InvalidArgumentException, InstantiationException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, org.hyperledger.fabric.sdk.exception.CryptoException, ProposalException, TransactionException {
        Trace result = traceRepository.save(trace);
        if(result != null){
            System.out.println(123);
            UserContext userContext = new UserContext();
            //userContext有某个组织的成员变量
            userContext.setAffiliation("Org1");//设置组织机构
            userContext.setMspId("Org1MSP");   //组织一的MSPID
            userContext.setAccount("dalin");
            userContext.setName("admin");
            Enrollment enrollment = UserUtils.getEnrollment(keyFolderPath,keyFileName,certFoldePath,certFileName);
            userContext.setEnrollment(enrollment);
            FabricClient fabricClient = new FabricClient(userContext);
            Peer peer0 = fabricClient.getPeer("peer0.org1.example.com","grpcs://peer0.org1.example.com:7051",peer0tlsFilePath);
            Peer peer1 = fabricClient.getPeer("peer1.org1.example.com","grpcs://peer1.org1.example.com:8051",peer1tlsFilePath);
            Orderer order = fabricClient.getOrderer("orderer.example.com","grpcs://orderer.example.com:7050",ordertlsFilePath);
            List<Peer> peers =new ArrayList<>();
            peers.add(peer0);
            peers.add(peer1);

            String str = "{\"traceability_id\""+":"+'"'+result.getTraceability_id()+'"'+","+"\"name\""+":"+'"'+result.getName()+'"'+","+"\"date_of_manufacture\""+":"+'"'+result.getDate_of_manufacture()+'"'+","+"\"manufactor\""+":"+'"'+result.getManufactor()+'"'+","+"\"telephone\""+":"+'"'+result.getTelephone()+'"'+","+"\"listing_date\""+":"+'"'+result.getListing_date()+'"'+","+"\"courier_number\""+":"+'"'+result.getCourier_number()+'"'+","+"\"term_of_validity\""+":"+'"'+result.getTerm_of_validity()+'"'+","+"\"company\""+":"+'"'+result.getCompany()+'"'+","+"\"tel\""+":"+'"'+result.getTel()+'"'+","+"\"delivery_date\""+":"+'"'+result.getDelivery_date()+'"'+"}";
            String initArgs[] = {result.getTraceability_id(),str};
            fabricClient.invoke("mychannel", TransactionRequest.Type.GO_LANG, "eight","1.0",order,peers,"save",initArgs);
            System.out.println("123执行了");
            return "success";
        }else{
            return "error";
        }
    }


    @PostMapping("/save")
    public String save(@RequestBody Trace trace) throws InvalidKeySpecException, NoSuchAlgorithmException, CryptoException, IOException, IllegalAccessException, InvalidArgumentException, InstantiationException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, org.hyperledger.fabric.sdk.exception.CryptoException, ProposalException, TransactionException {

        Trace result = traceRepository.save(trace);
        if(result != null){
            return "success";
        }else{
            return "error";
        }
    }

}
